home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / MORIA2.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  19KB  |  718 lines

  1. /* source/moria2.c: misc code, mainly handles player movement, inventory, etc
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #include <stdio.h>
  10.  
  11. #include "config.h"
  12. #include "constant.h"
  13. #include "types.h"
  14. #include "externs.h"
  15.  
  16. #if defined(LINT_ARGS)
  17. static int see_wall(int, int, int);
  18. static int see_nothing(int, int, int);
  19. #else
  20. static int see_wall();
  21. #endif
  22.  
  23.  
  24. /* Change a trap from invisible to visible        -RAK-    */
  25. /* Note: Secret doors are handled here                 */
  26. void change_trap(y, x)
  27. register int y, x;
  28. {
  29.   register cave_type *c_ptr;
  30.   register inven_type *t_ptr;
  31.  
  32.   c_ptr = &cave[y][x];
  33.   t_ptr = &t_list[c_ptr->tptr];
  34.   if (t_ptr->tval == TV_INVIS_TRAP)
  35.     {
  36.       t_ptr->tval = TV_VIS_TRAP;
  37.       lite_spot(y, x);
  38.     }
  39.   else if (t_ptr->tval == TV_SECRET_DOOR)
  40.     {
  41.       /* change secret door to closed door */
  42.       t_ptr->index = OBJ_CLOSED_DOOR;
  43.       t_ptr->tval = object_list[OBJ_CLOSED_DOOR].tval;
  44.       t_ptr->tchar = object_list[OBJ_CLOSED_DOOR].tchar;
  45.       lite_spot(y, x);
  46.     }
  47. }
  48.  
  49.  
  50. /* Searches for hidden things.            -RAK-    */
  51. void search(y, x, chance)
  52. int y, x, chance;
  53. {
  54.   register int i, j;
  55.   register cave_type *c_ptr;
  56.   register inven_type *t_ptr;
  57.   register struct flags *p_ptr;
  58.   bigvtype tmp_str, tmp_str2;
  59.  
  60.   p_ptr = &py.flags;
  61.   if (p_ptr->confused > 0)
  62.     chance = chance / 10;
  63.   if ((p_ptr->blind > 0) || no_light())
  64.     chance = chance / 10;
  65.   if (p_ptr->image > 0)
  66.     chance = chance / 10;
  67.   for (i = (y - 1); i <= (y + 1); i++)
  68.     for (j = (x - 1); j <= (x + 1); j++)
  69.       if (randint(100) < chance)    /* always in_bounds here */
  70.     {
  71.       c_ptr = &cave[i][j];
  72.       /* Search for hidden objects           */
  73.       if (c_ptr->tptr != 0)
  74.         {
  75.           t_ptr = &t_list[c_ptr->tptr];
  76.           /* Trap on floor?               */
  77.           if (t_ptr->tval == TV_INVIS_TRAP)
  78.         {
  79.           objdes(tmp_str2, t_ptr, TRUE);
  80.           (void) sprintf(tmp_str,"You have found %s",tmp_str2);
  81.           msg_print(tmp_str);
  82.           change_trap(i, j);
  83.           end_find();
  84.         }
  85.           /* Secret door?               */
  86.           else if (t_ptr->tval == TV_SECRET_DOOR)
  87.         {
  88.           msg_print("You have found a secret door.");
  89.           change_trap(i, j);
  90.           end_find();
  91.         }
  92.           /* Chest is trapped?           */
  93.           else if (t_ptr->tval == TV_CHEST)
  94.         {
  95.           /* mask out the treasure bits */
  96.           if ((t_ptr->flags & CH_TRAPPED) > 1)
  97.             if (!known2_p(t_ptr))
  98.               {
  99.             known2(t_ptr);
  100.             msg_print("You have discovered a trap on the chest!");
  101.               }
  102.             else
  103.               msg_print("The chest is trapped!");
  104.         }
  105.         }
  106.     }
  107. }
  108.  
  109.  
  110. /* The running algorithm:            -CJS-
  111.  
  112.    Overview: You keep moving until something interesting happens.
  113.    If you are in an enclosed space, you follow corners. This is
  114.    the usual corridor scheme. If you are in an open space, you go
  115.    straight, but stop before entering enclosed space. This is
  116.    analogous to reaching doorways. If you have enclosed space on
  117.    one side only (that is, running along side a wall) stop if
  118.    your wall opens out, or your open space closes in. Either case
  119.    corresponds to a doorway.
  120.  
  121.    What happens depends on what you can really SEE. (i.e. if you
  122.    have no light, then running along a dark corridor is JUST like
  123.    running in a dark room.) The algorithm works equally well in
  124.    corridors, rooms, mine tailings, earthquake rubble, etc, etc.
  125.  
  126.    These conditions are kept in static memory:
  127.     find_openarea     You are in the open on at least one
  128.              side.
  129.     find_breakleft     You have a wall on the left, and will
  130.              stop if it opens
  131.     find_breakright     You have a wall on the right, and will
  132.              stop if it opens
  133.  
  134.    To initialize these conditions is the task of find_init. If
  135.    moving from the square marked @ to the square marked . (in the
  136.    two diagrams below), then two adjacent sqares on the left and
  137.    the right (L and R) are considered. If either one is seen to
  138.    be closed, then that side is considered to be closed. If both
  139.    sides are closed, then it is an enclosed (corridor) run.
  140.  
  141.      LL        L
  142.     @.           L.R
  143.      RR           @R
  144.  
  145.    Looking at more than just the immediate squares is
  146.    significant. Consider the following case. A run along the
  147.    corridor will stop just before entering the center point,
  148.    because a choice is clearly established. Running in any of
  149.    three available directions will be defined as a corridor run.
  150.    Note that a minor hack is inserted to make the angled corridor
  151.    entry (with one side blocked near and the other side blocked
  152.    further away from the runner) work correctly. The runner moves
  153.    diagonally, but then saves the previous direction as being
  154.    straight into the gap. Otherwise, the tail end of the other
  155.    entry would be perceived as an alternative on the next move.
  156.  
  157.        #.#
  158.       ##.##
  159.       .@...
  160.       ##.##
  161.        #.#
  162.  
  163.    Likewise, a run along a wall, and then into a doorway (two
  164.    runs) will work correctly. A single run rightwards from @ will
  165.    stop at 1. Another run right and down will enter the corridor
  166.    and make the corner, stopping at the 2.
  167.  
  168.     #@      1
  169.     ########### ######
  170.     2        #
  171.     #############
  172.     #
  173.  
  174.    After any move, the function area_affect is called to
  175.    determine the new surroundings, and the direction of
  176.    subsequent moves. It takes a location (at which the runner has
  177.    just arrived) and the previous direction (from which the
  178.    runner is considered to have come). Moving one square in some
  179.    direction places you adjacent to three or five new squares
  180.    (for straight and diagonal moves) to which you were not
  181.    previously adjacent.
  182.  
  183.        ...!      ...           EG Moving from 1 to 2.
  184.        .12!      .1.!          . means previously adjacent
  185.        ...!      ..2!          ! means newly adjacent
  186.            !!!
  187.  
  188.    You STOP if you can't even make the move in the chosen
  189.    direction. You STOP if any of the new squares are interesting
  190.    in any way: usually containing monsters or treasure. You STOP
  191.    if any of the newly adjacent squares seem to be open, and you
  192.    are also looking for a break on that side. (i.e. find_openarea
  193.    AND find_break) You STOP if any of the newly adjacent squares
  194.    do NOT seem to be open and you are in an open area, and that
  195.    side was previously entirely open.
  196.  
  197.    Corners: If you are not in the open (i.e. you are in a
  198.    corridor) and there is only one way to go in the new squares,
  199.    then turn in that direction. If there are more than two new
  200.    ways to go, STOP. If there are two ways to go, and those ways
  201.    are separated by a square which does not seem to be open, then
  202.    STOP.
  203.  
  204.    Otherwise, we have a potential corner. There are two new open
  205.    squares, which are also adjacent. One of the new squares is
  206.    diagonally located, the other is straight on (as in the
  207.    diagram). We consider two more squares further out (marked
  208.    below as ?).
  209.       .X
  210.      @.?
  211.       #?
  212.    If they are both seen to be closed, then it is seen that no
  213.    benefit is gained from moving straight. It is a known corner.
  214.    To cut the corner, go diagonally, otherwise go straight, but
  215.    pretend you stepped diagonally into that next location for a
  216.    full view next time. Conversely, if one of the ? squares is
  217.    not seen to be closed, then there is a potential choice. We check
  218.    to see whether it is a potential corner or an intersection/room entrance.
  219.    If the square two spaces straight ahead, and the space marked with 'X'
  220.    are both blank, then it is a potential corner and enter if find_examine
  221.    is set, otherwise must stop because it is not a corner. */
  222.  
  223. /* The cycle lists the directions in anticlockwise order, for    -CJS-
  224.    over two complete cycles. The chome array maps a direction on
  225.    to its position in the cycle.
  226. */
  227. static int cycle[] = { 1, 2, 3, 6, 9, 8, 7, 4, 1, 2, 3, 6, 9, 8, 7, 4, 1 };
  228. static int chome[] = { -1, 8, 9, 10, 7, -1, 11, 6, 5, 4 };
  229. static int find_openarea, find_breakright, find_breakleft, find_prevdir;
  230. static int find_direction; /* Keep a record of which way we are going. */
  231.  
  232. void find_init(dir)
  233. int dir;
  234. {
  235.   int row, col, deepleft, deepright;
  236.   register int i, shortleft, shortright;
  237.  
  238.   row = char_row;
  239.   col = char_col;
  240.   if (!mmove(dir, &row, &col))
  241.     find_flag = FALSE;
  242.   else
  243.     {
  244.       find_direction = dir;
  245.       find_flag = 1;
  246.       find_breakright = find_breakleft = FALSE;
  247.       find_prevdir = dir;
  248.       if (py.flags.blind < 1)
  249.     {
  250.       i = chome[dir];
  251.       deepleft = deepright = FALSE;
  252.       shortright = shortleft = FALSE;
  253.       if (see_wall(cycle[i+1], char_row, char_col))
  254.         {
  255.           find_breakleft = TRUE;
  256.           shortleft = TRUE;
  257.         }
  258.       else if (see_wall(cycle[i+1], row, col))
  259.         {
  260.           find_breakleft = TRUE;
  261.           deepleft = TRUE;
  262.         }
  263.       if (see_wall(cycle[i-1], char_row, char_col))
  264.         {
  265.           find_breakright = TRUE;
  266.           shortright = TRUE;
  267.         }
  268.       else if (see_wall(cycle[i-1], row, col))
  269.         {
  270.           find_breakright = TRUE;
  271.           deepright = TRUE;
  272.         }
  273.       if (find_breakleft && find_breakright)
  274.         {
  275.           find_openarea = FALSE;
  276.           if (dir & 1)
  277.         {        /* a hack to allow angled corridor entry */
  278.           if (deepleft && !deepright)
  279.             find_prevdir = cycle[i-1];
  280.           else if (deepright && !deepleft)
  281.             find_prevdir = cycle[i+1];
  282.         }
  283.           /* else if there is a wall two spaces ahead and seem to be in a
  284.          corridor, then force a turn into the side corridor, must
  285.          be moving straight into a corridor here */
  286.           else if (see_wall(cycle[i], row, col))
  287.         {
  288.           if (shortleft && !shortright)
  289.             find_prevdir = cycle[i-2];
  290.           else if (shortright && !shortleft)
  291.             find_prevdir = cycle[i+2];
  292.         }
  293.         }
  294.       else
  295.         find_openarea = TRUE;
  296.     }
  297.     }
  298.  
  299.   /* We must erase the player symbol '@' here, because sub3_move_light()
  300.      does not erase the previous location of the player when in find mode
  301.      and when find_prself is FALSE.  The player symbol is not draw at all
  302.      in this case while moving, so the only problem is on the first turn
  303.      of find mode, when the initial position of the character must be erased.
  304.      Hence we must do the erasure here.  */
  305.   if (! light_flag && ! find_prself)
  306.     print(loc_symbol(char_row, char_col), char_row, char_col);
  307.  
  308.   move_char(dir, TRUE);
  309.   if (find_flag == FALSE)
  310.     command_count = 0;
  311. }
  312.  
  313. void find_run()
  314. {
  315.   /* prevent infinite loops in find mode, will stop after moving 100 times */
  316.   if (find_flag++ > 100)
  317.     {
  318.       msg_print("You stop running to catch your breath.");
  319.       end_find();
  320.     }
  321.   else
  322.     move_char(find_direction, TRUE);
  323. }
  324.  
  325. /* Switch off the run flag - and get the light correct. -CJS- */
  326. void end_find()
  327. {
  328.   if (find_flag)
  329.     {
  330.       find_flag = FALSE;
  331.       move_light(char_row, char_col, char_row, char_col);
  332.     }
  333. }
  334.  
  335. /* Do we see a wall? Used in running.        -CJS- */
  336. static int see_wall(dir, y, x)
  337. int dir, y, x;
  338. {
  339.   char c;
  340.  
  341.   if (!mmove(dir, &y, &x))    /* check to see if movement there possible */
  342.     return TRUE;
  343. #ifdef MSDOS
  344.   else if ((c = loc_symbol(y, x)) == wallsym || c == '%')
  345. #else
  346. #ifdef ATARI_ST
  347.   else if ((c = loc_symbol(y, x)) == (unsigned char)240 || c == '%')
  348. #else
  349.   else if ((c = loc_symbol(y, x)) == '#' || c == '%')
  350. #endif
  351. #endif
  352.     return TRUE;
  353.   else
  354.     return FALSE;
  355. }
  356.  
  357. /* Do we see anything? Used in running.        -CJS- */
  358. static int see_nothing(dir, y, x)
  359. int dir, y, x;
  360. {
  361.   if (!mmove(dir, &y, &x))    /* check to see if movement there possible */
  362.     return FALSE;
  363.   else if (loc_symbol(y, x) == ' ')
  364.     return TRUE;
  365.   else
  366.     return FALSE;
  367. }
  368.  
  369.  
  370. /* Determine the next direction for a run, or if we should stop.  -CJS- */
  371. void area_affect(dir, y, x)
  372. int dir, y, x;
  373. {
  374.   int newdir, t, inv, check_dir, row, col;
  375.   register int i, max, option, option2;
  376.   register cave_type *c_ptr;
  377.  
  378.   if (py.flags.blind < 1)
  379.     {
  380.       option = 0;
  381.       option2 = 0;
  382.       dir = find_prevdir;
  383.       max = (dir & 1) + 1;
  384.       /* Look at every newly adjacent square. */
  385.       for(i = -max; i <= max; i++)
  386.     {
  387.       newdir = cycle[chome[dir]+i];
  388.       row = y;
  389.       col = x;
  390.       if (mmove(newdir, &row, &col))
  391.         {
  392.           /* Objects player can see (Including doors?) cause a stop. */
  393.           c_ptr = &cave[row][col];
  394.           if (player_light || c_ptr->tl || c_ptr->pl || c_ptr->fm)
  395.         {
  396.           if (c_ptr->tptr != 0)
  397.             {
  398.               t = t_list[c_ptr->tptr].tval;
  399.               if (t != TV_INVIS_TRAP && t != TV_SECRET_DOOR
  400.               && (t != TV_OPEN_DOOR || !find_ignore_doors))
  401.             {
  402.               end_find();
  403.               return;
  404.             }
  405.             }
  406.           /* Also Creatures        */
  407.           /* the monster should be visible since update_mon() checks
  408.              for the special case of being in find mode */
  409.           if (c_ptr->cptr > 1 && m_list[c_ptr->cptr].ml)
  410.             {
  411.               end_find();
  412.               return;
  413.             }
  414.           inv = FALSE;
  415.         }
  416.           else
  417.         inv = TRUE;    /* Square unseen. Treat as open. */
  418.  
  419.           if (c_ptr->fval <= MAX_OPEN_SPACE || inv)
  420.         {
  421.           if (find_openarea)
  422.             {
  423.               /* Have we found a break? */
  424.               if (i < 0)
  425.             {
  426.               if (find_breakright)
  427.                 {
  428.                   end_find();
  429.                   return;
  430.                 }
  431.             }
  432.               else if (i > 0)
  433.             {
  434.               if (find_breakleft)
  435.                 {
  436.                   end_find();
  437.                   return;
  438.                 }
  439.             }
  440.             }
  441.           else if (option == 0)
  442.             option = newdir;    /* The first new direction. */
  443.           else if (option2 != 0)
  444.             {
  445.               end_find();    /* Three new directions. STOP. */
  446.               return;
  447.             }
  448.           else if (option != cycle[chome[dir]+i-1])
  449.             {
  450.               end_find();    /* If not adjacent to prev, STOP */
  451.               return;
  452.             }
  453.           else
  454.             {
  455.               /* Two adjacent choices. Make option2 the diagonal,
  456.              and remember the other diagonal adjacent to the first
  457.              option. */
  458.               if ((newdir & 1) == 1)
  459.             {
  460.               check_dir = cycle[chome[dir]+i-2];
  461.               option2 = newdir;
  462.             }
  463.               else
  464.             {
  465.               check_dir = cycle[chome[dir]+i+1];
  466.               option2 = option;
  467.               option = newdir;
  468.             }
  469.             }
  470.         }
  471.           else if (find_openarea)
  472.         {
  473.           /* We see an obstacle. In open area, STOP if on a side
  474.              previously open. */
  475.           if (i < 0)
  476.             {
  477.               if (find_breakleft)
  478.             {
  479.               end_find();
  480.               return;
  481.             }
  482.               find_breakright = TRUE;
  483.             }
  484.           else if (i > 0)
  485.             {
  486.               if (find_breakright)
  487.             {
  488.               end_find();
  489.               return;
  490.             }
  491.               find_breakleft = TRUE;
  492.             }
  493.         }
  494.         }
  495.     }
  496.  
  497.       if (find_openarea == FALSE)
  498.     {    /* choose a direction. */
  499.       if (option2 == 0 || (find_examine && !find_cut))
  500.         {
  501.           /* There is only one option, or if two, then we always examine
  502.          potential corners and never cur known corners, so you step
  503.          into the straight option. */
  504.           if (option != 0)
  505.         find_direction = option;
  506.           if (option2 == 0)
  507.         find_prevdir = option;
  508.           else
  509.         find_prevdir = option2;
  510.         }
  511.       else
  512.         {
  513.           /* Two options! */
  514.           row = y;
  515.           col = x;
  516.           (void) mmove(option, &row, &col);
  517.           if (!see_wall(option, row, col)
  518.           || !see_wall(check_dir, row, col))
  519.         {
  520.           /* Don't see that it is closed off.  This could be a
  521.              potential corner or an intersection. */
  522.           if (find_examine && see_nothing(option, row, col)
  523.               && see_nothing(option2, row, col))
  524.             /* Can not see anything ahead and in the direction we are
  525.                turning, assume that it is a potential corner. */
  526.             {
  527.               find_direction = option;
  528.               find_prevdir = option2;
  529.             }
  530.           else
  531.             /* STOP: we are next to an intersection or a room */
  532.             end_find();
  533.         }
  534.           else if (find_cut)
  535.         {
  536.           /* This corner is seen to be enclosed; we cut the corner. */
  537.           find_direction = option2;
  538.           find_prevdir = option2;
  539.         }
  540.           else
  541.         {
  542.           /* This corner is seen to be enclosed, and we deliberately
  543.              go the long way. */
  544.           find_direction = option;
  545.           find_prevdir = option2;
  546.         }
  547.         }
  548.     }
  549.     }
  550. }
  551.  
  552.  
  553. /* AC gets worse                    -RAK-    */
  554. /* Note: This routine affects magical AC bonuses so that stores      */
  555. /*     can detect the damage.                     */
  556. int minus_ac(typ_dam)
  557. int32u typ_dam;
  558. {
  559.   register int i, j;
  560.   int tmp[6], minus;
  561.   register inven_type *i_ptr;
  562.   bigvtype out_val, tmp_str;
  563.  
  564.   i = 0;
  565.   if (inventory[INVEN_BODY].tval != TV_NOTHING)
  566.     {
  567.       tmp[i] = INVEN_BODY;
  568.       i++;
  569.     }
  570.   if (inventory[INVEN_ARM].tval != TV_NOTHING)
  571.     {
  572.       tmp[i] = INVEN_ARM;
  573.       i++;
  574.     }
  575.   if (inventory[INVEN_OUTER].tval != TV_NOTHING)
  576.     {
  577.       tmp[i] = INVEN_OUTER;
  578.       i++;
  579.     }
  580.   if (inventory[INVEN_HANDS].tval != TV_NOTHING)
  581.     {
  582.       tmp[i] = INVEN_HANDS;
  583.       i++;
  584.     }
  585.   if (inventory[INVEN_HEAD].tval != TV_NOTHING)
  586.     {
  587.       tmp[i] = INVEN_HEAD;
  588.       i++;
  589.     }
  590.   /* also affect boots */
  591.   if (inventory[INVEN_FEET].tval != TV_NOTHING)
  592.     {
  593.       tmp[i] = INVEN_FEET;
  594.       i++;
  595.     }
  596.   minus = FALSE;
  597.   if (i > 0)
  598.     {
  599.       j = tmp[randint(i) - 1];
  600.       i_ptr = &inventory[j];
  601.       if (i_ptr->flags & typ_dam)
  602.     {
  603.       objdes(tmp_str, &inventory[j], FALSE);
  604.       (void) sprintf(out_val, "Your %s resists damage!", tmp_str);
  605.       msg_print(out_val);
  606.       minus = TRUE;
  607.     }
  608.       else if ((i_ptr->ac+i_ptr->toac) > 0)
  609.     {
  610.       objdes(tmp_str, &inventory[j], FALSE);
  611.       (void) sprintf(out_val, "Your %s is damaged!", tmp_str);
  612.       msg_print(out_val);
  613.       i_ptr->toac--;
  614.       calc_bonuses();
  615.       minus = TRUE;
  616.     }
  617.     }
  618.   return(minus);
  619. }
  620.  
  621.  
  622. /* Corrode the unsuspecting person's armor         -RAK-     */
  623. void corrode_gas(kb_str)
  624. char *kb_str;
  625. {
  626. #ifdef ATARIST_MWC
  627.   int32u holder;
  628. #endif
  629.  
  630. #ifdef ATARIST_MWC
  631.   if (!minus_ac((int32u) (holder = TR_RES_ACID)))
  632. #else
  633.   if (!minus_ac((int32u) TR_RES_ACID))
  634. #endif
  635.     take_hit(randint(8), kb_str);
  636.   if (inven_damage(set_corrodes, 5) > 0)
  637.     msg_print("There is an acrid smell coming from your pack.");
  638. }
  639.  
  640.  
  641. /* Poison gas the idiot.                -RAK-    */
  642. void poison_gas(dam, kb_str)
  643. int dam;
  644. char *kb_str;
  645. {
  646.   take_hit(dam, kb_str);
  647.   py.flags.poisoned += 12 + randint(dam);
  648. }
  649.  
  650.  
  651. /* Burn the fool up.                    -RAK-    */
  652. void fire_dam(dam, kb_str)
  653. int dam;
  654. char *kb_str;
  655. {
  656.   if (py.flags.fire_resist)
  657.     dam = dam / 3;
  658.   if (py.flags.resist_heat > 0)
  659.     dam = dam / 3;
  660.   take_hit(dam, kb_str);
  661.   if (inven_damage(set_flammable, 3) > 0)
  662.     msg_print("There is smoke coming from your pack!");
  663. }
  664.  
  665.  
  666. /* Freeze him to death.                -RAK-    */
  667. void cold_dam(dam, kb_str)
  668. int dam;
  669. char *kb_str;
  670. {
  671.   if (py.flags.cold_resist)
  672.     dam = dam / 3;
  673.   if (py.flags.resist_cold > 0)
  674.     dam = dam / 3;
  675.   take_hit(dam, kb_str);
  676.   if (inven_damage(set_frost_destroy, 5) > 0)
  677.     msg_print("Something shatters inside your pack!");
  678. }
  679.  
  680.  
  681. /* Lightning bolt the sucker away.            -RAK-    */
  682. void light_dam(dam, kb_str)
  683. int dam;
  684. char *kb_str;
  685. {
  686.   if (py.flags.lght_resist)
  687.     take_hit((dam / 3), kb_str);
  688.   else
  689.     take_hit(dam, kb_str);
  690.   if (inven_damage(set_lightning_destroy, 3) > 0)
  691.     msg_print("There are sparks coming from your pack!");
  692. }
  693.  
  694.  
  695. /* Throw acid on the hapless victim            -RAK-    */
  696. void acid_dam(dam, kb_str)
  697. int dam;
  698. char *kb_str;
  699. {
  700.   register int flag;
  701. #ifdef ATARIST_MWC
  702.   int32u holder;
  703. #endif
  704.  
  705.   flag = 0;
  706. #ifdef ATARIST_MWC
  707.   if (minus_ac((int32u) (holder = TR_RES_ACID)))
  708. #else
  709.   if (minus_ac((int32u) TR_RES_ACID))
  710. #endif
  711.     flag = 1;
  712.   if (py.flags.acid_resist)
  713.     flag += 2;
  714.   take_hit (dam / (flag + 1), kb_str);
  715.   if (inven_damage(set_acid_affect, 3) > 0)
  716.     msg_print("There is an acrid smell coming from your pack!");
  717. }
  718.